package patterns.creational.singleton;

/**
 * 单例模式示例
 * 确保一个类只有一个实例，并提供一个全局访问点
 */
public class SingletonPattern {
    
    public static void main(String[] args) {
        // 测试饿汉式单例
        EagerSingleton eager1 = EagerSingleton.getInstance();
        EagerSingleton eager2 = EagerSingleton.getInstance();
        System.out.println("饿汉式单例是否相同: " + (eager1 == eager2));
        
        // 测试懒汉式单例
        LazySingleton lazy1 = LazySingleton.getInstance();
        LazySingleton lazy2 = LazySingleton.getInstance();
        System.out.println("懒汉式单例是否相同: " + (lazy1 == lazy2));
        
        // 测试双重检查锁定单例
        DCLSingleton dcl1 = DCLSingleton.getInstance();
        DCLSingleton dcl2 = DCLSingleton.getInstance();
        System.out.println("双重检查锁定单例是否相同: " + (dcl1 == dcl2));
        
        // 测试静态内部类单例
        StaticInnerSingleton inner1 = StaticInnerSingleton.getInstance();
        StaticInnerSingleton inner2 = StaticInnerSingleton.getInstance();
        System.out.println("静态内部类单例是否相同: " + (inner1 == inner2));
        
        // 测试枚举单例
        EnumSingleton enum1 = EnumSingleton.INSTANCE;
        EnumSingleton enum2 = EnumSingleton.INSTANCE;
        System.out.println("枚举单例是否相同: " + (enum1 == enum2));
        
        // 使用单例
        eager1.doSomething();
        lazy1.doSomething();
        dcl1.doSomething();
        inner1.doSomething();
        enum1.doSomething();
    }
}

/**
 * 饿汉式单例
 * 在类加载时就创建实例，线程安全但可能造成资源浪费
 */
class EagerSingleton {
    // 在类加载时就创建实例
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    
    // 私有构造函数，防止外部实例化
    private EagerSingleton() {
        System.out.println("EagerSingleton 被初始化");
    }
    
    // 提供全局访问点
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
    
    public void doSomething() {
        System.out.println("EagerSingleton 执行操作");
    }
}

/**
 * 懒汉式单例
 * 在第一次使用时才创建实例，需要同步保证线程安全
 */
class LazySingleton {
    // 声明但不初始化实例
    private static LazySingleton instance;
    
    // 私有构造函数
    private LazySingleton() {
        System.out.println("LazySingleton 被初始化");
    }
    
    // 同步方法，确保线程安全，但效率较低
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
    
    public void doSomething() {
        System.out.println("LazySingleton 执行操作");
    }
}

/**
 * 双重检查锁定单例
 * 在第一次使用时才创建实例，使用双重检查锁定提高效率
 */
class DCLSingleton {
    // volatile关键字确保多线程环境下的可见性
    private static volatile DCLSingleton instance;
    
    // 私有构造函数
    private DCLSingleton() {
        System.out.println("DCLSingleton 被初始化");
    }
    
    // 双重检查锁定，提高效率
    public static DCLSingleton getInstance() {
        if (instance == null) {
            synchronized (DCLSingleton.class) {
                if (instance == null) {
                    instance = new DCLSingleton();
                }
            }
        }
        return instance;
    }
    
    public void doSomething() {
        System.out.println("DCLSingleton 执行操作");
    }
}

/**
 * 静态内部类单例
 * 利用类加载机制保证线程安全，同时实现懒加载
 */
class StaticInnerSingleton {
    // 私有构造函数
    private StaticInnerSingleton() {
        System.out.println("StaticInnerSingleton 被初始化");
    }
    
    // 静态内部类，只有在首次调用getInstance()时才会被加载
    private static class SingletonHolder {
        private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
    }
    
    // 提供全局访问点
    public static StaticInnerSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    
    public void doSomething() {
        System.out.println("StaticInnerSingleton 执行操作");
    }
}

/**
 * 枚举单例
 * 最简洁的实现，自动支持序列化，绝对防止多次实例化
 */
enum EnumSingleton {
    INSTANCE;
    
    EnumSingleton() {
        System.out.println("EnumSingleton 被初始化");
    }
    
    public void doSomething() {
        System.out.println("EnumSingleton 执行操作");
    }
} 